//
//  RESTfulEngine.m
//  PrintFamily
//
//  Created by 戴怀诚 on 15/7/3.
//  Copyright (c) 2015年 戴怀诚. All rights reserved.
//

#import "RESTfulEngine.h"
#import "RESTfulOperation.h"

@implementation RESTfulEngine

#define kAccessTokenDefaultsKey @"ACCESS_TOKEN"

- (NSString*)accessToken {
    if (!_accessToken) {
        _accessToken = [[NSUserDefaults standardUserDefaults] stringForKey:kAccessTokenDefaultsKey];
    }
    return _accessToken;
}

-(void)setAccessToken:(NSString *)aAccessToken
{
    _accessToken = aAccessToken;
    
    // if you are going to have multiple accounts support,
    // it's advisable to store the access token as a serialized object
    // this code will break when a second RESTfulEngine object is instantiated and a new token is issued for him
    
    [[NSUserDefaults standardUserDefaults] setObject:self.accessToken forKey:kAccessTokenDefaultsKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)removeAccessToken {
    
    self.accessToken = @"";
    
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"kAccessTokenDefaultsKey"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (RESTfulOperation*)allocRestfulOperationWithPath:(NSString*)path params:param httpMethod:(NSString*)method succeededBlock:(OneSenderBlock)succeededBlock errorBlock:(ErrorBlock)errorBlock {
    
    RESTfulOperation *op = (RESTfulOperation*)[self operationWithPath:path params:param httpMethod:method];
    
    [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
        NSDictionary *response = [completedOperation responseJSON];
        succeededBlock(response);
    } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
        errorBlock(error);
    }];
    
    [self enqueueOperation:op];
    
    return op;
}

- (RESTfulOperation*)allocRestfulOperationWithPath:(NSString*)path params:param httpMethod:(NSString*)method voidSucceededBlock:(VoidBlock)voidBlock errorBlock:(ErrorBlock)errorBlock {
    RESTfulOperation *op = (RESTfulOperation*)[self operationWithPath:path params:param httpMethod:method];
    
    [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
        voidBlock();
    } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
        errorBlock(error);
    }];
    
    [self enqueueOperation:op];
    
    return op;
}

#pragma mark - register && login
// Url:
- (id)loginWithName:(NSString *)loginName
              vcode:(NSString *)vcode
        onSucceeded:(VoidBlock)succeededBlock
            onError:(ErrorBlock)errorBlock
{
    NSDictionary *param = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:loginName, vcode, nil] forKeys:[NSArray arrayWithObjects:@"username", @"vcode", nil]];
    
    RESTfulOperation *op = (RESTfulOperation*)[self operationWithPath:@"/api/login/" params:param httpMethod:@"POST"];
    
    [op setUsername:loginName password:vcode basicAuth:YES];
    
    [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
        NSDictionary *responseDict = [completedOperation responseJSON];
        
        self.accessToken = [responseDict objectForKey:@"token"];
        succeededBlock();
    } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
        self.accessToken = nil;
        errorBlock(error);
    }];
    
    [self enqueueOperation:op];
    
    return op;
}

- (id)requestUploadTokenOnSucceeded:(OneSenderBlock)succeededBlock
                        onError:(ErrorBlock)errorBlock {
    
    RESTfulOperation *op = (RESTfulOperation*)[self operationWithPath:@"/api/upload_token/" params:nil httpMethod:@"GET"];
    
    [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
        succeededBlock([completedOperation responseJSON]);
    } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {
        errorBlock(error);
    }];
    
    [self enqueueOperation:op];

    return op;
}

- (void)prepareHeaders:(MKNetworkOperation *)operation {
    if (self.accessToken && self.accessToken.length > 0) {
        [operation setAuthorizationHeaderValue:self.accessToken forAuthType:@"Token"];
    } else {
        [operation setAuthorizationHeaderValue:nil forAuthType:@"Token"];
    }
    [super prepareHeaders:operation];
}

@end
